# encoding:utf-8
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import sessionmaker, scoped_session
from contextlib import contextmanager
from tornado.options import options

def make_engine():
    if 'ENGINE' not in dir():
        global ENGINE
        ENGINE=create_engine(options.database, encoding="utf-8", echo=False)
        ENGINE.dialect.supports_sane_rowcount = ENGINE.dialect.supports_sane_multi_rowcount = False
    return ENGINE


@contextmanager
def session_scope():
    DBSession = sessionmaker(bind=make_engine(),
                             autocommit=False, autoflush=True,
                             expire_on_commit=False)
    session = DBSession()
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()


class Base(object):
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

    __mapper_args__ = {'always_refresh': True}

    def to_dict(self):
        columns = self.__table__.columns.keys()
        res_dict = dict()
        for var in columns:
            res_dict[var] = getattr(self, var)
        return res_dict


BaseModel = declarative_base(cls=Base)


def init_db():
    from model.user import User
    BaseModel.metadata.create_all(bind=make_engine())
    auth = User(secret_key='7O55TVX18QBBO1G1VFT7QBQF0RDLNKE2', access_key='38SVOPBJ1MJ45GM7EWGVF9COUF7JD9A1',
                permission='*', is_superuser=True)
    db = scoped_session(sessionmaker(bind=ENGINE,
                                     autocommit=False, autoflush=True,
                                     expire_on_commit=False))
    db.add(auth)
    db.commit()


def drop_db():
    engine = BaseModel.session()
    BaseModel.metadata.drop_all(engine.engine)
